/*
 * DataReader.cpp
 *
 *  Created on: Nov 17, 2010
 *      Author: dblyth
 */

#include "DataReader.h"
#include "chid.h"
#include "crystalMap.h"
#include "TFile.h"
#include "TTree.h"
#include "TBranch.h"
#include <iostream>

using namespace std;
DataReader::DataReader(string baseDir, int runNum, bool expandNew) {
	expand = expandNew;
	int loop = 6;
	if (expand)
		loop = 9;
	for (int l = 0; l < loop; l++) {
		string fileName = baseDir;
		stringstream s;
		s.fill('0');
		s.width(4);
		switch (l) {
		case 0:
			s << runNum;
			fileName += "crate0_run" + s.str() + "_conv.root";
			crate0 = new TFile(fileName.c_str());
			tree0 = (TTree*) crate0->Get("EventTree");
			break;
		case 1:
			s << runNum;
			fileName += "crate1_run" + s.str() + "_conv.root";
			crate1 = new TFile(fileName.c_str());
			tree1 = (TTree*) crate1->Get("EventTree");
			break;
		case 2:
			s << runNum;
			fileName += "crate2_run" + s.str() + "_conv.root";
			crate2 = new TFile(fileName.c_str());
			tree2 = (TTree*) crate2->Get("EventTree");
			break;
		case 3:
			s << runNum;
			fileName += "crate3_run" + s.str() + "_conv.root";
			crate3 = new TFile(fileName.c_str());
			tree3 = (TTree*) crate3->Get("EventTree");
			break;
		case 4:
			s << runNum;
			fileName += "crate4_run" + s.str() + "_conv.root";
			crate4 = new TFile(fileName.c_str());
			tree4 = (TTree*) crate4->Get("EventTree");
			break;
		case 5:
			s << runNum;
			fileName += "crate5_run" + s.str() + "_conv.root";
			crate5 = new TFile(fileName.c_str());
			tree5 = (TTree*) crate5->Get("EventTree");
			break;
		case 6:
			s << runNum;
			fileName += "crate6_run" + s.str() + "_conv.root";
			crate6 = new TFile(fileName.c_str());
			tree6 = (TTree*) crate6->Get("EventTree");
			break;
		case 7:
			s << runNum;
			fileName += "crate7_run" + s.str() + "_conv.root";
			crate7 = new TFile(fileName.c_str());
			tree7 = (TTree*) crate7->Get("EventTree");
			break;
		case 8:
			s << runNum;
			fileName += "crate8_run" + s.str() + "_conv.root";
			crate8 = new TFile(fileName.c_str());
			tree8 = (TTree*) crate8->Get("EventTree");
		}
	}
}

DataReader::~DataReader() {
	crate0->Close();
	crate1->Close();
	crate2->Close();
	crate3->Close();
	crate4->Close();
	crate5->Close();
	if (expand) {
		crate6->Close();
		crate7->Close();
		crate8->Close();
	}
}

int** DataReader::GetData(int eventNum, double* energy) {
	const short max = 2760;
	int** dataOutput = new int*[max];
	for (int i = 0; i < max; i++)
		dataOutput[i] = NULL;

	int loop = 6;
	if (expand)
		loop = 9;
	for (int l = 0; l < loop; l++) {
		TTree* eventTree;
		switch (l) {
		case 0:
			eventTree = tree0;
			break;
		case 1:
			eventTree = tree1;
			break;
		case 2:
			eventTree = tree2;
			break;
		case 3:
			eventTree = tree3;
			break;
		case 4:
			eventTree = tree4;
			break;
		case 5:
			eventTree = tree5;
			break;
		case 6:
			eventTree = tree6;
			break;
		case 7:
			eventTree = tree7;
			break;
		case 8:
			eventTree = tree8;
		}

		TBranch* dataBranch = eventTree->GetBranch("Data");
		if (eventNum >= dataBranch->GetEntryNumber()) {
			delete[] dataOutput;
			return NULL;
		}
		int dataTemp[20][16][48];
		dataBranch->SetAddress(&dataTemp);
		dataBranch->GetEntry(eventNum);

		TBranch* nFADCBranch = eventTree->GetBranch("nFADC");
		int nFADC;
		nFADCBranch->SetAddress(&nFADC);
		nFADCBranch->GetEntry(eventNum);

		TBranch* pedestalBranch = eventTree->GetBranch("Pedestal");
		int pedestal[20][16];
		pedestalBranch->SetAddress(&pedestal);
		pedestalBranch->GetEntry(eventNum);

		double energyTemp[20][16];
		if (expand) {
			TBranch* energyBranch = eventTree->GetBranch("Sum");
			energyBranch->SetAddress(&energyTemp);
			energyBranch->GetEvent(eventNum);
		} else {
			for (int i = 0; i < 20; i++) {
				for (int j = 0; j < 16; j++)
					energyTemp[i][j] = 0;
			}
		}

		for (int i = 0; i < nFADC; i++) {
			for (int j = 0; j < 16; j++) {
				int crystalNum;
				switch (l) {
				case 0:
					crystalNum = Crate0_CHID[i][j];
					break;
				case 1:
					crystalNum = Crate1_CHID[i][j];
					break;
				case 2:
					crystalNum = Crate2_CHID[i][j];
					break;
				case 3:
					crystalNum = Crate3_CHID[i][j];
					break;
				case 4:
					crystalNum = Crate4_CHID[i][j];
					break;
				case 5:
					crystalNum = Crate5_CHID[i][j];
					break;
				case 6:
					crystalNum = Crate6_CHID[i][j];
					break;
				case 7:
					crystalNum = Crate7_CHID[i][j];
					break;
				case 8:
					crystalNum = Crate8_CHID[i][j];
				}
				if (crystalNum < 0)
					continue;
				if (dataOutput[crystalNum] != NULL)
					continue;
				dataOutput[crystalNum] = new int[51];
				int xPos = crystalMap[crystalNum][0];
				int yPos = crystalMap[crystalNum][1];
				dataOutput[crystalNum][48] = xPos;
				dataOutput[crystalNum][49] = yPos;
				dataOutput[crystalNum][50] = pedestal[i][j];
				energy[crystalNum] = energyTemp[i][j];
				for (int k = 0; k < 48; k++) {
					dataOutput[crystalNum][k] = dataTemp[i][j][k];
				}
			}
		}
	}

	return dataOutput;
}
